package com.example.observer.dubbo;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Objects;

public interface EventListener<E extends Event> extends java.util.EventListener,Prioritized {

    static Class<? extends Event> findEventType(EventListener<?> listener) {
        return findEventType(listener.getClass());
    }

    static Class<? extends Event> findEventType(Class<?> listenerClass) {
        Class<? extends Event> eventType = null;

        if (listenerClass!= null && EventListener.class.isAssignableFrom(listenerClass)) {

            eventType = ReflectUtils.findParameterizedTypes(listenerClass).stream()
                    .filter(Objects::nonNull)
                    .map(EventListener::findEventType)
                    .findAny()
                    .orElse(findEventType(listenerClass.getSuperclass()));

        }

        return eventType;
    }


    static Class<? extends Event> findEventType(ParameterizedType parameterizedType) {
        Class<? extends Event> eventType = null;
        Type rawType = parameterizedType.getRawType();
        if (rawType instanceof Class && EventListener.class.isAssignableFrom((Class<?>) rawType)) {
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                if (actualTypeArgument instanceof Class) {
                    Class aClass = Class.class.cast(actualTypeArgument);
                    if (Event.class.isAssignableFrom(aClass)) {
                        eventType = aClass;
                        break;
                    }
                }
            }
        }
        return eventType;
    }

    void onEvent(E event);




}
